package command;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.mail.Session;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import command2.*;
import common.CookieUtils;
import common.Crypto;
import common.UserSession;

import org.apache.log4j.Logger;

import db.CommonConnect;
import db.DAO;
import db.QueryManager;

/**
 * Command객체를 가지고 있는 HashMap을 정의하는 클래스.
 */
public class CommandManager {

	/**
	 * 로그인한 상태에서 실행할 Command를 담는 Map.
	 *
	 */
	private static HashMap commands;

	/**
	 * 로그인 안한 상태에서 실행할 Command를 담는 Map.
	 */
	private static HashMap commandsFree;
	protected static Logger logger = Logger.getLogger(CommandManager.class);


	public static void initCommandsFree() { // 로그인을 하지 않아도 되는 명령
		commandsFree = new HashMap(); // commandsFree라는 해시맵 객체 선언
		
		
		commandsFree.put("session_error", new NullCommand("/jsp/msg/session_error.jsp"));
		commandsFree.put("download", new NullCommand("/jsp/downloadFile.jsp"));
		commandsFree.put("download2", new NullCommand("/jsp/downloadFile2.jsp"));

		//commandsFree.put("admin_intro", new IndexCommand("/jsp/index.jsp"));
		
		commandsFree.put("admin_intro", new NullCommand("/jsp/index.jsp"));
		commandsFree.put("login", new OpMainCommand("/jsp/main.jsp"));

		
		/*우편번호 찾기*/
		commandsFree.put("address", new NullCommand("/jsp/address_list.jsp"));
		commandsFree.put("address_list", new Address_listCommand("/jsp/address_list.jsp"));
	}

	/**
	 * Command 클래스들을 key 값에 맞게 HashMap 객체에 올려놓는다.
	 */
	public static void initCommands() { // 로그인을 해야만 동작 하는 명령
		commands = new HashMap(); // commands라는 해시맵 객체 선언

		/*
		commands.put("test_input", new NullCommand("/jsp/test_input.jsp"));
		commands.put("test_insert", new TestInsert("/jsp/test_insert.jsp"));
		*/
		commands.put("logout", new LogoutCommand("/jsp/index.jsp"));
		
		commands.put("main", new NullCommand("/jsp/main.jsp"));
		
		/*난이도 관리*/
		commands.put("level_main", new LevelCommand("/jsp/sp_sp0101_list.jsp"));
	
		commands.put("level_select", new LevelSelectCommand("/jsp/sp_sp0101_select.jsp"));
		commands.put("level_insert", new LevelInsertCommand("/jsp/sp_sp0101_proc.jsp"));
		commands.put("level_modify", new LevelModifyCommand("/jsp/sp_sp0101_proc.jsp"));
		commands.put("level_delete", new LevelDeleteCommand("/jsp/sp_sp0101_proc.jsp"));
		
		/*대분류 관리*/
		commands.put("lrg_main", new LrgCommand("/jsp/sp_sp0102_list.jsp"));	
		commands.put("lrg_select", new LrglSelectCommand("/jsp/sp_sp0102_select.jsp"));
		commands.put("lrg_insert", new LrgInsertCommand("/jsp/sp_sp0102_proc.jsp"));
		commands.put("lrg_modify", new LrgModifyCommand("/jsp/sp_sp0102_proc.jsp"));
		commands.put("lrg_delete", new LrgDeleteCommand("/jsp/sp_sp0102_proc.jsp"));
		
		/*중분류 관리*/
		commands.put("sml_main", new SmlCommand("/jsp/sp_sp0103_list.jsp"));		
		commands.put("sml_select", new SmlSelectCommand("/jsp/sp_sp0103_select.jsp"));
		commands.put("sml_insert", new SmlInsertCommand("/jsp/sp_sp0103_proc.jsp"));
		commands.put("sml_modify", new SmlModifyCommand("/jsp/sp_sp0103_proc.jsp"));
		commands.put("sml_delete", new SmlDeleteCommand("/jsp/sp_sp0103_proc.jsp"));
		
		/*등급별 문제 난이도 관리*/
		commands.put("grade_main", new GradeCommand("/jsp/sp_sp0104_list.jsp"));	
		commands.put("grade_select", new GradeSelectCommand("/jsp/sp_sp0104_select.jsp"));
		commands.put("grade_insert", new GradeInsertCommand("/jsp/sp_sp0104_proc.jsp"));
		commands.put("grade_modify", new GradeModifyCommand("/jsp/sp_sp0104_proc.jsp"));
		commands.put("grade_delete", new GradeDeleteCommand("/jsp/sp_sp0104_proc.jsp"));
		
		/*opic 문제 관리*/
		commands.put("opicexam_main", new OpicExamCommand("/jsp/sp_sp0106_list.jsp"));
		commands.put("opicexam_input", new NullCommand("/jsp/sp_sp0106_input.jsp"));
		commands.put("opicexam_select", new OpicExamSelectCommand("/jsp/sp_sp0106_modify.jsp"));
		commands.put("opicexam_insert", new OpicExamInsertCommand("/jsp/sp_sp0106_proc.jsp"));
		commands.put("opicexam_modify", new OpicExamModifyCommand("/jsp/sp_sp0106_proc.jsp"));
		commands.put("opicexam_delete", new OpicExamDeleteCommand("/jsp/sp_sp0106_proc.jsp"));
		
		
		/*토익스피킹 카테고리 관리 관리*/
		commands.put("cate_main", new CateCommand("/jsp/sp_sp0201_list.jsp"));	
		commands.put("cate_select", new CateSelectCommand("/jsp/sp_sp0201_select.jsp"));
		commands.put("cate_insert", new CateInsertCommand("/jsp/sp_sp0201_proc.jsp"));
		commands.put("cate_modify", new CateModifyCommand("/jsp/sp_sp0201_proc.jsp"));
		commands.put("cate_delete", new CateDeleteCommand("/jsp/sp_sp0201_proc.jsp"));
		
		/*ts 문제 관리*/
		commands.put("tsexam_main", new TsExamCommand("/jsp/sp_sp0202_list.jsp"));
		commands.put("tsexam_input", new NullCommand("/jsp/sp_sp0202_input.jsp"));
		commands.put("tsexam_select", new TsExamSelectCommand("/jsp/sp_sp0202_modify.jsp"));
		commands.put("tsexam_insert", new TsExamInsertCommand("/jsp/sp_sp0202_proc.jsp"));
		commands.put("tsexam_modify", new TsExamModifyCommand("/jsp/sp_sp0202_proc.jsp"));
		commands.put("tsexam_delete", new TsExamDeleteCommand("/jsp/sp_sp0202_proc.jsp"));
		
		/*prep 카테고리 관리 관리*/
		commands.put("prep_cate_main", new PrepCateCommand("/jsp/sp_sp1101_list.jsp"));	
		commands.put("prep_cate_select", new PrepCateSelectCommand("/jsp/sp_sp1101_select.jsp"));
		commands.put("prep_cate_insert", new PrepCateInsertCommand("/jsp/sp_sp1101_proc.jsp"));
		commands.put("prep_cate_modify", new PrepCateModifyCommand("/jsp/sp_sp1101_proc.jsp"));
		commands.put("prep_cate_delete", new PrepCateDeleteCommand("/jsp/sp_sp1101_proc.jsp"));
		
		/*prep 문제 관리*/
		commands.put("prepexam_main", new PrepExamCommand("/jsp/sp_sp1102_list.jsp"));
		commands.put("prepexam_input", new NullCommand("/jsp/sp_sp1102_input.jsp"));
		commands.put("prepexam_select", new PrepExamSelectCommand("/jsp/sp_sp1102_modify.jsp"));
		commands.put("prepexam_insert", new PrepExamInsertCommand("/jsp/sp_sp1102_proc.jsp"));
		commands.put("prepexam_modify", new PrepExamModifyCommand("/jsp/sp_sp1102_proc.jsp"));
		commands.put("prepexam_delete", new PrepExamDeleteCommand("/jsp/sp_sp1102_proc.jsp"));
		
		
		
		/*Prep 시험 관리*/
		commands.put("preptest_main", new PreptestCommand("/jsp/sp_sp1201_list.jsp"));		
		commands.put("preptest_select", new PreptestSelectCommand("/jsp/sp_sp1201_modify.jsp"));		
		commands.put("preptest_modify", new PreptestModifyCommand("/jsp/sp_sp1201_proc.jsp"));
		commands.put("preptest_rerating", new PreptestReratingCommand("/jsp/sp_sp1201_proc.jsp"));
		commands.put("preptest_delete", new PreptestDeleteCommand("/jsp/sp_sp1201_proc.jsp"));
		commands.put("preptest_reteststate", new PreptestReteststateCommand("/jsp/sp_sp1201_proc.jsp"));
		
		commands.put("preptest_result", new PreptestResultCommand("/jsp/sp_sp1201_result.jsp"));
		
		
		/*opic 시험 관리*/
		commands.put("opictest_main", new OpictestCommand("/jsp/sp_sp0301_list.jsp"));		
		commands.put("opictest_select", new OpictestSelectCommand("/jsp/sp_sp0301_modify.jsp"));		
		commands.put("opictest_modify", new OpictestModifyCommand("/jsp/sp_sp0301_proc.jsp"));
		commands.put("opictest_rerating", new OpictestReratingCommand("/jsp/sp_sp0301_proc.jsp"));
		commands.put("opictest_delete", new OpictestDeleteCommand("/jsp/sp_sp0301_proc.jsp"));
		commands.put("opictest_reteststate", new OpictestReteststateCommand("/jsp/sp_sp0301_proc.jsp"));
		
		commands.put("opictest_result", new OpictestResultCommand("/jsp/sp_sp0301_result.jsp"));
		
		/*ts 시험 관리*/
		commands.put("tstest_main", new TstestCommand("/jsp/sp_sp0401_list.jsp"));		
		commands.put("tstest_select", new TstestSelectCommand("/jsp/sp_sp0401_modify.jsp"));		
		commands.put("tstest_modify", new TstestModifyCommand("/jsp/sp_sp0401_proc.jsp"));
		commands.put("tstest_rerating", new TstestReratingCommand("/jsp/sp_sp0401_proc.jsp"));
		commands.put("tstest_delete", new TstestDeleteCommand("/jsp/sp_sp0401_proc.jsp"));
		commands.put("tstest_reteststate", new TstestReteststateCommand("/jsp/sp_sp0401_proc.jsp"));
		
		commands.put("tstest_result", new TstestResultCommand("/jsp/sp_sp0401_result.jsp"));
		
		/*시험통계*/
		commands.put("statistics_opic", new StatisticsOpicCommand("/jsp/sp_sp0501_opic_list.jsp"));
		commands.put("statistics_ts", new StatisticsTsCommand("/jsp/sp_sp0501_ts_list.jsp"));
		commands.put("statistics_prep", new StatisticsPrepCommand("/jsp/sp_sp0501_prep_list.jsp"));
		commands.put("statistics_ent", new NullCommand("/jsp/sp_sp0501_ent_list.jsp"));
		commands.put("statistics_ent_1", new StatisticsEntCommand_1("/jsp/sp_sp0501_ent_list_1.jsp"));
		commands.put("statistics_ent_2", new StatisticsEntCommand_2("/jsp/sp_sp0501_ent_list_2.jsp"));
		commands.put("statistics_ent_3", new StatisticsEntCommand_3("/jsp/sp_sp0501_ent_list_3.jsp"));
		commands.put("statistics_rater", new StatisticsRaterCommand("/jsp/sp_sp0501_rater_list.jsp"));
		commands.put("statistics_rater_excel", new StatisticsRaterCommand("/jsp/sp_sp0501_rater_excel.jsp"));
		
		commands.put("opic_stats", new NullCommand("/jsp/sp_sp0501_opic_stats.jsp"));
		commands.put("opic_stats_1", new StatisticsOpicStatsCommand_1("/jsp/sp_sp0501_opic_stats_1.jsp"));
		commands.put("opic_stats_2", new StatisticsOpicStatsCommand_2("/jsp/sp_sp0501_opic_stats_2.jsp"));
		commands.put("opic_stats_3", new StatisticsOpicStatsCommand_3("/jsp/sp_sp0501_opic_stats_3.jsp"));
		commands.put("opic_stats_4", new StatisticsOpicStatsCommand_4("/jsp/sp_sp0501_opic_stats_4.jsp"));
		commands.put("opic_stats_5", new StatisticsOpicStatsCommand_5("/jsp/sp_sp0501_opic_stats_5.jsp"));
		
		commands.put("prep_stats", new NullCommand("/jsp/sp_sp0501_prep_stats.jsp"));
		commands.put("prep_stats_1", new StatisticsOpicStatsCommand_1("/jsp/sp_sp0501_prep_stats_1.jsp"));
		commands.put("prep_stats_2", new StatisticsOpicStatsCommand_2("/jsp/sp_sp0501_prep_stats_2.jsp"));
		commands.put("prep_stats_3", new StatisticsOpicStatsCommand_3("/jsp/sp_sp0501_prep_stats_3.jsp"));
		commands.put("prep_stats_4", new StatisticsOpicStatsCommand_4("/jsp/sp_sp0501_prep_stats_4.jsp"));
		commands.put("prep_stats_5", new StatisticsOpicStatsCommand_5("/jsp/sp_sp0501_prep_stats_5.jsp"));
		
		commands.put("ts_stats", new NullCommand("/jsp/sp_sp0501_ts_stats.jsp"));
		commands.put("ts_stats_1", new StatisticsOpicStatsCommand_1("/jsp/sp_sp0501_ts_stats_1.jsp"));
		commands.put("ts_stats_2", new StatisticsOpicStatsCommand_2("/jsp/sp_sp0501_ts_stats_2.jsp"));
		commands.put("ts_stats_3", new StatisticsOpicStatsCommand_3("/jsp/sp_sp0501_ts_stats_3.jsp"));
		commands.put("ts_stats_4", new StatisticsOpicStatsCommand_4("/jsp/sp_sp0501_ts_stats_4.jsp"));
		commands.put("ts_stats_5", new StatisticsOpicStatsCommand_5("/jsp/sp_sp0501_ts_stats_5.jsp"));
		
		/*학습자 로그 보기*/
		commands.put("member_test_first_log", new MemberTestFirstLogCommand("/jsp/sp_member_first_log_list.jsp"));
		commands.put("member_test_log", new MemberTestLogCommand("/jsp/sp_member_log_list.jsp"));
		
		commands.put("member_opic_stats", new NullCommand("/jsp/sp_member_opic_stats.jsp"));
		commands.put("member_opic_stats_1", new MemberTestOpicStatsCommand_1("/jsp/sp_member_opic_stats_1.jsp"));
		commands.put("member_opic_stats_2", new MemberTestOpicStatsCommand_2("/jsp/sp_member_opic_stats_2.jsp"));
		commands.put("member_opic_stats_3", new MemberTestOpicStatsCommand_3("/jsp/sp_member_opic_stats_3.jsp"));
		
		commands.put("member_ts_stats", new NullCommand("/jsp/sp_member_ts_stats.jsp"));
		commands.put("member_ts_stats_1", new MemberTestOpicStatsCommand_1("/jsp/sp_member_ts_stats_1.jsp"));
		commands.put("member_ts_stats_2", new MemberTestOpicStatsCommand_2("/jsp/sp_member_ts_stats_2.jsp"));
		commands.put("member_ts_stats_3", new MemberTestOpicStatsCommand_3("/jsp/sp_member_ts_stats_3.jsp"));
		
		/*회원 관리*/
		commands.put("member_main", new MemberCommand("/jsp/sp_sp0601_list.jsp"));
		commands.put("member_input", new NullCommand("/jsp/sp_sp0601_input.jsp"));
		commands.put("member_select", new MemberSelectCommand("/jsp/sp_sp0601_modify.jsp"));
		commands.put("member_insert", new MemberInsertCommand("/jsp/sp_sp0601_proc.jsp"));
		commands.put("member_modify", new MemberModifyCommand("/jsp/sp_sp0601_proc.jsp"));
		commands.put("member_delete", new MemberDeleteCommand("/jsp/sp_sp0601_proc.jsp"));
		
		/*rater 관리*/
		commands.put("rater_main", new RaterCommand("/jsp/sp_sp0701_list.jsp"));
		commands.put("rater_input", new NullCommand("/jsp/sp_sp0701_input.jsp"));
		commands.put("rater_select", new RaterSelectCommand("/jsp/sp_sp0701_modify.jsp"));
		commands.put("rater_insert", new RaterInsertCommand("/jsp/sp_sp0701_proc.jsp"));
		commands.put("rater_modify", new RaterModifyCommand("/jsp/sp_sp0701_proc.jsp"));
		commands.put("rater_delete", new RaterDeleteCommand("/jsp/sp_sp0701_proc.jsp"));
		
		
		/*기업 관리*/
		commands.put("ent_main", new EntCommand("/jsp/sp_sp0901_list.jsp"));
		commands.put("ent_input", new NullCommand("/jsp/sp_sp0901_input.jsp"));
		commands.put("ent_select", new EntSelectCommand("/jsp/sp_sp0901_modify.jsp"));
		commands.put("ent_view", new EntSelectCommand("/jsp/sp_sp0901_view.jsp"));
		commands.put("ent_insert", new EntInsertCommand("/jsp/sp_sp0901_proc.jsp"));
		commands.put("ent_modify", new EntModifyCommand("/jsp/sp_sp0901_proc.jsp"));
		commands.put("ent_delete", new EntDeleteCommand("/jsp/sp_sp0901_proc.jsp"));
		
		
		/*관리자 관리*/
		commands.put("admin_main", new AdminCommand("/jsp/sp_sp0801_list.jsp"));
		commands.put("admin_input", new NullCommand("/jsp/sp_sp0801_input.jsp"));
		commands.put("admin_select", new AdminSelectCommand("/jsp/sp_sp0801_modify.jsp"));
		commands.put("admin_view", new AdminSelectCommand("/jsp/sp_sp0801_view.jsp"));
		commands.put("admin_insert", new AdminInsertCommand("/jsp/sp_sp0801_proc.jsp"));
		commands.put("admin_modify", new AdminModifyCommand("/jsp/sp_sp0801_proc.jsp"));
		commands.put("admin_delete", new AdminDeleteCommand("/jsp/sp_sp0801_proc.jsp"));
		commands.put("admin_setup", new AdminSelectCommand("/jsp/sp_sp0801_setup.jsp"));
		
		commands.put("id_chk", new IdChkCommand("/jsp/msg/ajax_id_text.jsp"));
		commands.put("rater_give", new raterGiveCommand("/jsp/msg/ajax_rater_text.jsp"));

			
		/*Rater Comment 대분류 관리*/
		commands.put("rrg_main", new RrgCommand("/jsp/sp_sp1001_list.jsp"));	
		commands.put("rrg_select", new RrglSelectCommand("/jsp/sp_sp1001_select.jsp"));
		commands.put("rrg_insert", new RrgInsertCommand("/jsp/sp_sp1001_proc.jsp"));
		commands.put("rrg_modify", new RrgModifyCommand("/jsp/sp_sp1001_proc.jsp"));
		commands.put("rrg_delete", new RrgDeleteCommand("/jsp/sp_sp1001_proc.jsp"));
		
		/*Rater Comment 중분류 관리*/
		commands.put("rsml_main", new RsmlCommand("/jsp/sp_sp1002_list.jsp"));		
		commands.put("rsml_select", new RsmlSelectCommand("/jsp/sp_sp1002_select.jsp"));
		commands.put("rsml_insert", new RsmlInsertCommand("/jsp/sp_sp1002_proc.jsp"));
		commands.put("rsml_modify", new RsmlModifyCommand("/jsp/sp_sp1002_proc.jsp"));
		commands.put("rsml_delete", new RsmlDeleteCommand("/jsp/sp_sp1002_proc.jsp"));
		
		
		
		/*Rater prep Comment 대분류 관리*/
		commands.put("prep_rrg_main", new PrepRrgCommand("/jsp/sp_sp1301_list.jsp"));	
		commands.put("prep_rrg_select", new PrepRrglSelectCommand("/jsp/sp_sp1301_select.jsp"));
		commands.put("prep_rrg_insert", new PrepRrgInsertCommand("/jsp/sp_sp1301_proc.jsp"));
		commands.put("prep_rrg_modify", new PrepRrgModifyCommand("/jsp/sp_sp1301_proc.jsp"));
		commands.put("prep_rrg_delete", new PrepRrgDeleteCommand("/jsp/sp_sp1301_proc.jsp"));
		
		/*Rater prep Comment 중분류 관리*/
		commands.put("prep_rsml_main", new PrepRsmlCommand("/jsp/sp_sp1302_list.jsp"));		
		commands.put("prep_rsml_select", new PrepRsmlSelectCommand("/jsp/sp_sp1302_select.jsp"));
		commands.put("prep_rsml_insert", new PrepRsmlInsertCommand("/jsp/sp_sp1302_proc.jsp"));
		commands.put("prep_rsml_modify", new PrepRsmlModifyCommand("/jsp/sp_sp1302_proc.jsp"));
		commands.put("prep_rsml_delete", new PrepRsmlDeleteCommand("/jsp/sp_sp1302_proc.jsp"));
		
	}

	private CommandManager() {

	}

	/**
	 * cmd값에 따라 해당 Command를 불러오는 기능을 함.
	 *
	 * @param cmd
	 *            명령 매개변수
	 * @param session
	 *            HttpSession
	 * @return 명령 클래스Command를 리턴함
	 *
	 */
	public static Command lookupCommand(String cmd, HttpServletRequest request)
	throws CommandException {

		if (cmd == null) { // command가 null 이면 메인화면으로... //cmd로 받아온 값이 null이면,
			cmd = "admin_intro"; 
		}

		HttpSession session     = request.getSession(true);
		UserSession userSession = (UserSession) session.getAttribute("user");
		String user_id  = null;
		
		Boolean debug   = true;  // 디버그 STEP을 출력할것인지 여부 (안정적인 서비스시에는 false로 놓을것을 추천)

		String user_ip   = request.getRemoteAddr();
		String train_url = request.getServerName();
		Map map = null;

		if(debug) System.out.println("---- CommandManager Session & Cookie CHECK STEP ----");
		
		

		if(debug) System.out.println("##### [STEP1] Session에 등록된 사용자 정보를 확인 ##### ");
	    // ************* /// UserSession 세션값이 존재하지 않을경우  START
		if (userSession == null) {

			if(request.getCookies() != null) {
				if(debug) System.out.println("     : 쿠키["+request.getCookies() + "로부터 사용자 정보를 탐색 합니다.");

				// 쿠키에서 login_id를 가져온다
				Cookie cookie = null;
				String id = "";
				Cookie[] cookies = request.getCookies();
				if (cookies != null) {
					for (int i = 0; i < cookies.length; i++) {
						cookie = cookies[i];
						if (cookie.getName().equals("usid")) {
							id = (String) (cookie.getValue());
						}
					}
				} // IF cookies != null

				if (id != null && !id.equals("")) {
					if(debug) System.out.println("     : [Cookie:usid] ==> " + id);
					if(debug) System.out.println("     : [user_ip]     ==> " + user_ip);

					// login_id를 복화처리한다.
					String d_id = Crypto.DecodeBySType2(id, user_ip);
					if(debug) System.out.println("     : [Decode_ID]   ==> " + d_id);

					if (d_id.length() > 6) {
						if (d_id.substring(d_id.length() - 6, d_id.length()).equals("speake")) {
							//if (map != null && map.containsKey("login_id")) {
							map = getUserInfoByCookies(request.getCookies(),  user_ip);
							if (map != null) {
								userSession = (UserSession) new UserSession(map);
								session.setAttribute("user", userSession);

								user_id = userSession.getLogin_id();
								if(debug) System.out.println("     : [유효쿠키] Session에 사용자 정보를 재설정 하였습니다.[user_id :"	+ user_id + "] ");
								if(debug) System.out.println("     : 현재 로그인 수 : :"+ userSession.getSessionCnt() + " 명 ");
							} else {
								if(debug) System.out.println("     : [Exception] 쿠키로부터 UserSession MAP 정보를 가져오지 못했습니다.");
							}
							//}
						} else {
							session.setAttribute("ERROR_TYPE","COOKIE");
							if(debug) System.out.println("     : [Exception] 정상적으로 발급된 쿠키정보가 아닙니다.");
							throw new CommandException("잘못된 쿠키정보입니다 !!!");
						}
					}
				} else {
					System.out.println(" cmd["+cmd+"]");
					

					if(debug) System.out.println("     : 쿠키로부터 사용자 정보를 찾을수 없습니다.");
				}
			} else {
				if(debug) System.out.println("     : Session 및 쿠키로부터 사용자 정보를 찾을 수 없습니다.");
			}

		// ************* /// UserSession 세션값이 존재할 경우  START
		} else {
			user_id = userSession.getLogin_id();
			if(debug) System.out.println("     : Session에 등록된 사용자 정보 확인 [user_id :"+ user_id + "] ");
			if(debug) System.out.println("     : 현재 로그인 된 수 : :"+ userSession.getSessionCnt() + " 명 ");
		}
		if(debug) System.out.println("----------------------------------------------------");


		// 로그인 후 접근가능 userid가 널이 아니고 commands에 값이 있으면.
		if (user_id != null && commands.containsKey(cmd.toLowerCase())) {
			// 소문자 cmd값을 commands에서  가져와서 돌려줌.
			return (Command) commands.get(cmd.toLowerCase());

		// 비회원 접근가능 소문자 cmd값이 commandsFree객체에 있나 확인
		} else if (commandsFree.containsKey(cmd.toLowerCase())) {
			// 있으면 commandsFree에서 그 값을 Command로 형변환 후 가져옴(Null Command)
			return (Command) commandsFree.get(cmd.toLowerCase());

		// userid값이 null이면,
		} else if (user_id == null && commands.containsKey(cmd.toLowerCase())) {
			cmd = "session_error"; // cmd에 세션에러라는 값을 넣어줌.
			// 그리고 commandsFree에서 세션에러라는 값을 소문자로 가져와 Command로 형변환 후 돌려줌
			return (Command) commandsFree.get(cmd.toLowerCase());

		} else {
			throw new CommandException("Invalide Command !!"); // 이도저도 아니라면
		}
	}

	/**
	 * 사용자 세션이 timeout 으로 끊어졌을경우, 현재 브라우져 세션이 존재하는 쿠키의 사용자 ID 를 통해 새로운 사용자 세션을
	 * 설정 한다. TODO 이전에 사용자가 인증서로 로그인 한경우, timeout 되었다면, 쿠키를 통해 새로운 사용자 세션을 맺어줄때
	 * 인증서 여부를 어떻게 설정할 것인가?
	 *
	 * @param cookies
	 * @return 사용자 정보
	 */
	private static Map getUserInfoByCookies(Cookie[] cookies,String user_ip) {
		System.out.println("     : [getUserInfoByCookies()] 쿠키로부터 UserSession MAP 정보를 가져옵니다.");
		String usid = Crypto.DecodeBySType2(CookieUtils.getValue(cookies,"usid"),user_ip); // 사용자 id

		// 로그인여부 
		Map        map = null;
		Connection con = null;
		if (usid != null) {
			usid = usid.substring(0, usid.length() - 6);
			System.out.println("     : [getUserInfoByCookies()] usid => " + usid );

			// ********** /// 디비에서 접근 유효한 정보인지 확인 START
			try {
				con = (new CommonConnect()).getConnection_ds1();
				String[] param = null;
				String queryStr = QueryManager.getQuery("loginbyCookie.query");
				param    = new String[1];
				param[0] = usid;				
				ArrayList list = DAO.select(con, queryStr, param);
				if (list == null || list.size() == 0) {
					throw new CommandException("This is not available IDCookie!");
				} else map = (HashMap) list.get(0);

			} catch (Exception ex) {
				logger.error(ex.getMessage());
			} finally {
				try {
					if (con != null) con.close();
				} catch (Exception ee) { }
			}
			// ********** /// 디비에서 접근 유효한 정보인지 확인 STOP
		} else {
			return null;
		}
		return map;
	}


}
